import * as crypto from 'crypto';
import { Buffer } from 'buffer';

const algorithm = 'aes-128-cbc'; // 生成密码的加密格式
const UTF_8 = 'utf-8'; // 编码格式
const encoding = 'base64'; // 输出加密格式
const iterations = 10000; // 密匙迭代次数，次数越高越安全，但消耗资源
const keylen = 16; // 生成密匙字节长度
const strType = 'hex'; // 转换字符串的类型为哈希类型
// 自定义随机盐值
const salt = (len = 6) => {
  let keyCode = '';
  let orgStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  for (let i = 0; i < len; i++) {
    keyCode += orgStr.charAt(Math.floor(Math.random() * orgStr.length));
  }
  return keyCode;
};
// 自定义随机iv向量
const iv = (len = 16) => {
  let keyCode = '';
  for (let i = 0; i < len; i++) {
    keyCode += Math.floor(Math.random() * 10).toString();
  }
  return keyCode;
};
// 加密
export const encryption = (pwd) => {
  const salts = salt(12); // 盐值
  const ivs = iv(); // 自定义向量
  const customPwd = salt(12); // 自定义密匙

  // 生产加密的密匙类型为Buffer二进制流哈希编码数据类型
  const key = crypto.pbkdf2Sync(customPwd, salts, iterations, keylen, 'sha256');
  // 加密方式，注意key部分只接受二进制流数据，否则就报错超出长度
  const cipher = crypto.createCipheriv(algorithm, key, ivs);
  // 传入需要加密的内容与输出的加密格式
  let encStr = cipher.update(pwd, UTF_8, encoding);
  // 拼接获取加密后的内容
  encStr += cipher.final(encoding);
  return {
    password: encStr,
    key: key.toString(strType), // 将二进制流hex编码转换为哈希类型的字符串
    iv: ivs,
  };
};
// 解密
export const decode = (pwd, key, iv) => {
  // 将密匙转换成buffer类型
  const _key = Buffer.alloc(keylen, key, strType);
  // 传入密码格式，该密码密匙，该密码自定义向量，来判断通过什么方式解密
  const decipher = crypto.createDecipheriv(algorithm, _key, iv);
  // 传入需要解密内容与输出格式进行解密
  let decstr = decipher.update(pwd, encoding, UTF_8);
  // 获取到解密后的内容
  decstr += decipher.final(UTF_8);
  return decstr;
};
